<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Numbers</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Chapter 1. Boost.JSON">
<link rel="up" href="../dom.html" title="Document Model">
<link rel="prev" href="object.html" title="object">
<link rel="next" href="conversion.html" title="Value Conversion">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="object.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../dom.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="conversion.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="json.dom.numbers"></a><a class="link" href="numbers.html" title="Numbers">Numbers</a>
</h3></div></div></div>
<p>
        JSON numbers are represented using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">int64_t</span></code>,
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">uint64_t</span></code>, and <code class="computeroutput"><span class="keyword">double</span></code>.
        When a <a class="link" href="../ref/boost__json__value.html" title="value"><code class="computeroutput"><span class="identifier">value</span></code></a>
        is constructed from an unsigned integer, its <a class="link" href="../ref/boost__json__kind.html" title="kind"><code class="computeroutput"><span class="identifier">kind</span></code></a> will be <code class="computeroutput"><span class="identifier">kind</span><span class="special">::</span><span class="identifier">uint64</span></code>.
        Likewise, a <a class="link" href="../ref/boost__json__value.html" title="value"><code class="computeroutput"><span class="identifier">value</span></code></a>
        constructed from a signed integer will have <code class="computeroutput"><span class="identifier">kind</span><span class="special">::</span><span class="identifier">int64</span></code>,
        or <code class="computeroutput"><span class="identifier">kind</span><span class="special">::</span><span class="identifier">double_</span></code> if constructed from a floating-point
        type:
      </p>
<pre class="programlisting"><span class="comment">// construction from int</span>
<span class="identifier">value</span> <span class="identifier">jv1</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>

<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">jv1</span><span class="special">.</span><span class="identifier">is_int64</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// construction from unsigned int</span>
<span class="identifier">value</span> <span class="identifier">jv2</span> <span class="special">=</span> <span class="number">2u</span><span class="special">;</span>

<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">jv2</span><span class="special">.</span><span class="identifier">is_uint64</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// construction from double</span>
<span class="identifier">value</span> <span class="identifier">jv3</span> <span class="special">=</span> <span class="number">3.0</span><span class="special">;</span>

<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">jv3</span><span class="special">.</span><span class="identifier">is_double</span><span class="special">()</span> <span class="special">);</span>
</pre>
<p>
        When accessing a number contained within a <a class="link" href="../ref/boost__json__value.html" title="value"><code class="computeroutput"><span class="identifier">value</span></code></a>, the function used must match
        the value's <a class="link" href="../ref/boost__json__kind.html" title="kind"><code class="computeroutput"><span class="identifier">kind</span></code></a>
        exactly; no conversions will be performed. For example if <code class="computeroutput"><span class="identifier">as_double</span></code>
        is called on a <a class="link" href="../ref/boost__json__value.html" title="value"><code class="computeroutput"><span class="identifier">value</span></code></a> that contains a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">uint64_t</span></code>,
        an exception is thrown. Similarly, the function <code class="computeroutput"><span class="identifier">if_double</span></code>
        will return <code class="computeroutput"><span class="keyword">nullptr</span></code> and calling
        <code class="computeroutput"><span class="identifier">get_double</span></code> will result in
        undefined behavior:
      </p>
<pre class="programlisting"><span class="identifier">value</span> <span class="identifier">jv</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>

<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">jv</span><span class="special">.</span><span class="identifier">is_int64</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// jv.kind() != kind::uint64; throws</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">uint64_t</span> <span class="identifier">r1</span> <span class="special">=</span> <span class="identifier">jv</span><span class="special">.</span><span class="identifier">as_uint64</span><span class="special">();</span>

<span class="comment">// jv.kind() != kind::uint64; the behavior is undefined</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">uint64_t</span> <span class="identifier">r2</span> <span class="special">=</span> <span class="identifier">jv</span><span class="special">.</span><span class="identifier">get_uint64</span><span class="special">();</span>

<span class="comment">// if_double will always return nullptr, branch is not taken</span>
<span class="keyword">if</span><span class="special">(</span><span class="keyword">double</span><span class="special">*</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">jv</span><span class="special">.</span><span class="identifier">if_double</span><span class="special">())</span>
    <span class="identifier">assert</span><span class="special">(</span> <span class="keyword">false</span> <span class="special">);</span>
</pre>
<p>
        In cases where you know that a <a class="link" href="../ref/boost__json__value.html" title="value"><code class="computeroutput"><span class="identifier">value</span></code></a> contains a number but don't
        know its <a class="link" href="../ref/boost__json__kind.html" title="kind"><code class="computeroutput"><span class="identifier">kind</span></code></a>,
        <a class="link" href="../ref/boost__json__value_to.html" title="value_to"><code class="computeroutput"><span class="identifier">value_to</span></code></a>
        can be used to convert the <a class="link" href="../ref/boost__json__value.html" title="value"><code class="computeroutput"><span class="identifier">value</span></code></a> to an arithmetic type:
      </p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">convert_int64</span>
<span class="special">{</span>
    <span class="identifier">value</span> <span class="identifier">jv</span><span class="special">;</span>

    <span class="keyword">operator</span> <span class="keyword">int</span><span class="special">()</span> <span class="keyword">const</span>
    <span class="special">{</span>
        <span class="keyword">return</span> <span class="identifier">value_to</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">jv</span> <span class="special">);</span>
    <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
        If the <a class="link" href="../ref/boost__json__value.html" title="value"><code class="computeroutput"><span class="identifier">value</span></code></a>
        does not contain a number, or if the conversion is to an integer type <code class="computeroutput"><span class="identifier">T</span></code> and the number cannot be represented
        exactly by <code class="computeroutput"><span class="identifier">T</span></code>, the conversion
        will fail. Otherwise, the result is the number converted to <code class="computeroutput"><span class="identifier">T</span></code> as-if by <code class="computeroutput"><span class="keyword">static_cast</span></code>:
      </p>
<pre class="programlisting"><span class="identifier">value</span> <span class="identifier">jv1</span> <span class="special">=</span> <span class="number">404</span><span class="special">;</span>

<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">jv1</span><span class="special">.</span><span class="identifier">is_int64</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// ok, identity conversion</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">int64_t</span> <span class="identifier">r1</span> <span class="special">=</span> <span class="identifier">value_to</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">int64_t</span> <span class="special">&gt;(</span> <span class="identifier">jv1</span> <span class="special">);</span>

<span class="comment">// loss of data, throws system_error</span>
<span class="keyword">char</span> <span class="identifier">r2</span> <span class="special">=</span> <span class="identifier">value_to</span><span class="special">&lt;</span> <span class="keyword">char</span> <span class="special">&gt;(</span> <span class="identifier">jv1</span> <span class="special">);</span>

<span class="comment">// ok, no loss of data</span>
<span class="keyword">double</span> <span class="identifier">r3</span> <span class="special">=</span> <span class="identifier">value_to</span><span class="special">&lt;</span> <span class="keyword">double</span> <span class="special">&gt;(</span> <span class="identifier">jv1</span> <span class="special">);</span>

<span class="identifier">value</span> <span class="identifier">jv2</span> <span class="special">=</span> <span class="number">1.23</span><span class="special">;</span>

<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">jv1</span><span class="special">.</span><span class="identifier">is_double</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// ok, same as static_cast&lt;float&gt;( jv2.get_double() )</span>
<span class="keyword">float</span> <span class="identifier">r4</span> <span class="special">=</span> <span class="identifier">value_to</span><span class="special">&lt;</span> <span class="keyword">float</span> <span class="special">&gt;(</span> <span class="identifier">jv2</span> <span class="special">);</span>

<span class="comment">// not exact, throws system_error</span>
<span class="keyword">int</span> <span class="identifier">r5</span> <span class="special">=</span> <span class="identifier">value_to</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span> <span class="identifier">jv2</span> <span class="special">);</span>

<span class="identifier">value</span> <span class="identifier">jv3</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>

<span class="identifier">assert</span><span class="special">(</span> <span class="special">!</span> <span class="identifier">jv3</span><span class="special">.</span><span class="identifier">is_number</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// not a number, throws system_error</span>
<span class="keyword">int</span> <span class="identifier">r6</span> <span class="special">=</span> <span class="identifier">value_to</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span> <span class="identifier">jv3</span> <span class="special">);</span>
</pre>
<p>
        Arithmetic conversions done by <a class="link" href="../ref/boost__json__value_to.html" title="value_to"><code class="computeroutput"><span class="identifier">value_to</span></code></a> delegate to <code class="computeroutput"><span class="identifier">value</span><span class="special">::</span><span class="identifier">to_number</span></code>. In settings where exceptions
        cannot be used, an overload of <code class="computeroutput"><span class="identifier">value</span><span class="special">::</span><span class="identifier">to_number</span></code>
        accepting <a class="link" href="../ref/boost__json__error_code.html" title="error_code"><code class="computeroutput"><span class="identifier">error_code</span></code></a> can be used instead with
        identical semantics to its throwing counterpart:
      </p>
<pre class="programlisting"><span class="identifier">value</span> <span class="identifier">jv</span> <span class="special">=</span> <span class="number">10.5</span><span class="special">;</span>

<span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">;</span>

<span class="comment">// ok, conversion is exact</span>
<span class="keyword">float</span> <span class="identifier">r1</span> <span class="special">=</span> <span class="identifier">jv</span><span class="special">.</span><span class="identifier">to_number</span><span class="special">&lt;</span> <span class="keyword">float</span> <span class="special">&gt;(</span> <span class="identifier">ec</span> <span class="special">);</span>

<span class="identifier">assert</span><span class="special">(</span> <span class="special">!</span> <span class="identifier">ec</span> <span class="special">);</span>

<span class="comment">// error, conversion is non-exact</span>
<span class="keyword">int</span> <span class="identifier">r2</span> <span class="special">=</span> <span class="identifier">jv</span><span class="special">.</span><span class="identifier">to_number</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span> <span class="identifier">ec</span> <span class="special">);</span>

<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">ec</span> <span class="special">==</span> <span class="identifier">error</span><span class="special">::</span><span class="identifier">not_exact</span> <span class="special">);</span>
</pre>
<p>
        When parsing a JSON document, the type used to represent a number is not
        explicitly specified and must be determined from its value. In general, the
        parser will choose the best type which can accurately store the number as
        it appears in the document. Integers (i.e. numbers without decimals or exponents)
        that cannot be represented by <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">uint64_t</span></code>
        and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">int64_t</span></code> will be represented as <code class="computeroutput"><span class="keyword">double</span></code> to preserve their magnitude:
      </p>
<pre class="programlisting"><span class="identifier">value</span> <span class="identifier">jv</span> <span class="special">=</span> <span class="identifier">parse</span><span class="special">(</span><span class="string">"[-42, 100, 10.25, -299999999999999999998, 2e32]"</span><span class="special">);</span>

<span class="identifier">array</span> <span class="identifier">ja</span> <span class="special">=</span> <span class="identifier">jv</span><span class="special">.</span><span class="identifier">as_array</span><span class="special">();</span>

<span class="comment">// represented by std::int64_t</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">ja</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">is_int64</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// represented by std::int64_t</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">ja</span><span class="special">[</span><span class="number">1</span><span class="special">].</span><span class="identifier">is_int64</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// contains decimal point, represented as double</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">ja</span><span class="special">[</span><span class="number">2</span><span class="special">].</span><span class="identifier">is_double</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// less than INT64_MIN, represented as double</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">ja</span><span class="special">[</span><span class="number">3</span><span class="special">].</span><span class="identifier">is_double</span><span class="special">()</span> <span class="special">);</span>

<span class="comment">// contains exponent, represented as double</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="identifier">ja</span><span class="special">[</span><span class="number">4</span><span class="special">].</span><span class="identifier">is_double</span><span class="special">()</span> <span class="special">);</span>
</pre>
<p>
        More formally, if the number:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            contains a decimal point, or
          </li>
<li class="listitem">
            contains an exponent, or
          </li>
<li class="listitem">
            is negative and its value is less than <code class="computeroutput"><span class="identifier">INT64_MIN</span></code>,
            or
          </li>
<li class="listitem">
            is positive and its value is greater than <code class="computeroutput"><span class="identifier">UINT64_MAX</span></code>,
          </li>
</ul></div>
<p>
        then its type is <code class="computeroutput"><span class="keyword">double</span></code>. Otherwise,
        if the number is positive and its value is greater than <code class="computeroutput"><span class="identifier">INT64_MAX</span></code>,
        then its type is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">uint64_t</span></code>. All other numbers are parsed
        as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">int64_t</span></code>.
      </p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2019, 2020 Vinnie Falco<br>Copyright © 2020 Krystian Stasiowski<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="object.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../dom.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="conversion.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
